package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.factory.OptionFactory;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.handle.AbstractOptionHandle;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.ColumnSortPojo;
import com.xbongbong.paas.pojo.dto.ColumnSetAddDTO;
import com.xbongbong.paas.pojo.dto.ColumnSetListDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.ColumnSetAddVO;
import com.xbongbong.paas.pojo.vo.ColumnSetListVO;
import com.xbongbong.paas.service.CallCenterCommonService;
import com.xbongbong.paas.service.LaneColumnConfigService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.parent.explain.FormDataListFormExplainHandleName;
import com.xbongbong.pro.config.pojo.dto.UserConfigSaveBatchDTO;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.ListOptionEnum;
import com.xbongbong.saas.help.SaasHelp;
import com.xbongbong.sys.domain.entity.UserConfigEntity;
import com.xbongbong.sys.enums.UserConfigEnum;
import com.xbongbong.sys.model.UserConfigModel;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2022/02/21 10:21
 */
@Service("laneColumnConfigService")
public class LaneColumnConfigServiceImpl extends UserConfigServiceImpl implements LaneColumnConfigService {

    @Resource
    private OptionFactory optionFactory;
    @Resource
    private FormDataListFormExplainHandleName formDataListFormExplainHandleName;
    @Resource
    private UserConfigModel userConfigModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private SaasHelp saasHelp;
    @Resource
    private CallCenterCommonService callCenterCommonService;


    @Override
    public ColumnSetListVO laneColumnList(ColumnSetListDTO columnSetListDTO) throws XbbException {
        ColumnSetListVO columnSetListVO = new ColumnSetListVO();
        Map<String, Object> resultMap = new HashMap<>();
        String userId = columnSetListDTO.getUserId();
        String corpid = columnSetListDTO.getCorpid();
        Long appId = columnSetListDTO.getAppId();
        Long formId = columnSetListDTO.getFormId();
        String laneDefaultSortConfigAlias = UserConfigEnum.LANE_DEFAULT_SORT_FIELD.getAlias()+"_"+ + appId + "_" + formId;
        String laneListSortFieldConfigAlias = UserConfigEnum.LANE_LIST_SORT_FIELD.getAlias()+"_"+ + appId + "_" + formId;
        String laneListShowFieldConfigAlias = UserConfigEnum.LANE_LIST_SHOW_FIELD.getAlias()+"_"+ + appId + "_" + formId;
        String laneCountFieldConfigAlias = UserConfigEnum.LANE_COUNT_FIELD.getAlias()+"_"+ + appId + "_" + formId;
        String laneShowTitleConfigAlias = UserConfigEnum.LANE_SHOW_TITLE.getAlias()+"_"+ + appId + "_" + formId;
        Map<String, Object> params = new HashMap<>();
        List<String> configAliasList = new ArrayList<>();
        configAliasList.add(laneDefaultSortConfigAlias);
        configAliasList.add(laneListSortFieldConfigAlias);
        configAliasList.add(laneListShowFieldConfigAlias);
        configAliasList.add(laneCountFieldConfigAlias);
        configAliasList.add(laneShowTitleConfigAlias);
        params.put("configAliasIn", configAliasList);
        params.put("userId", userId);
        params.put("corpid", corpid);
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        List<UserConfigEntity> userConfigList = userConfigModel.list(params);
        // 判断是否有呼叫权限
        boolean isActiveCall = callCenterCommonService.isOpenCallAndAgent(corpid, userId);
        // 判断是否有阿里云呼叫中心权限
        boolean isActiveAliyunCall = callCenterCommonService.isActiveAliyunCall(corpid,userId).IsActiveAliyunAndHasRole();

        if (CollectionsUtil.isNotEmpty(userConfigList)) {
            userConfigList.forEach(e -> {
                if (Objects.equals(e.getConfigAlias(), laneDefaultSortConfigAlias)) {
                    resultMap.put("defaultSortField", JSONObject.parseObject(e.getConfigValue()));
                } else if (Objects.equals(e.getConfigAlias(), laneListSortFieldConfigAlias)) {
                    JSONArray jsonArray = JSONObject.parseArray(e.getConfigValue());
                    setOption_3(jsonArray);
                    Iterator iterator = jsonArray.iterator();
                    while (iterator.hasNext()) {
                        JSONObject map = (JSONObject) iterator.next();
                        if (Objects.equals(map.get("attr"),ListOptionEnum.CALL.getAttr())&&!isActiveCall&&!isActiveAliyunCall) {
                            iterator.remove();
                            break;
                        }
                    }
                    resultMap.put("laneListSortField", jsonArray);
                } else if (Objects.equals(e.getConfigAlias(), laneListShowFieldConfigAlias)) {
                    resultMap.put("laneListShowField", JSONArray.parseArray(e.getConfigValue()));
                } else if (Objects.equals(e.getConfigAlias(), laneCountFieldConfigAlias)) {
                    resultMap.put("laneCountField", e.getConfigValue());
                } else if (Objects.equals(e.getConfigAlias(), laneShowTitleConfigAlias)) {
                    resultMap.put("showTitle", Integer.parseInt(e.getConfigValue()));
                }
            });
        } else {
            JSONObject defaultSortField = new JSONObject();
            JSONArray laneListShowField = new JSONArray();
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), columnSetListDTO.getSaasMark())) {
                //查询出所有操作按钮
                if (Objects.equals(columnSetListDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                    List<FieldAttrEntity> explainList = new ArrayList<>();
                    FormDataListDTO formDataListDTO = new FormDataListDTO();
                    formDataListDTO.setCorpid(columnSetListDTO.getCorpid());
                    formDataListDTO.setUserId(columnSetListDTO.getUserId());
                    formDataListDTO.setLoginUser(columnSetListDTO.getLoginUser());
                    formDataListDTO.setBusinessType(columnSetListDTO.getBusinessType());
                    AbstractOptionHandle abstractOptionHandle = optionFactory.getByBusinessType(columnSetListDTO.getBusinessType(), columnSetListDTO.getSaasMark());
                    if (Objects.nonNull(abstractOptionHandle)) {
                        abstractOptionHandle.setOptionsInExplain(formDataListDTO, explainList, null);
                        if (CollectionsUtil.isNotEmpty(explainList)) {
                            for (FieldAttrEntity temp : explainList) {
                                laneListShowField.add(temp.getAttr());
                            }
                        }
                    }
                }
                //查询出数据摘要的5个
                PaasFormEntity paasFormEntity = paasFormModel.getByFormId(formId, corpid);
                JSONArray summary = JSONArray.parseArray(paasFormEntity.getSummary());
                for (int i = 0; i < summary.size(); i++) {
                    JSONObject temp = summary.getJSONObject(i);
                    String attr = temp.getString("attr");
                    if (StringUtil.isNotEmpty(attr)&&attr.contains("geo")){
                        continue;
                    }
                    laneListShowField.add(attr);
                }
                if (CollectionsUtil.isEmpty(summary)) {
                    PaasFormExplainEntity formExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
                    List<FieldAttrEntity> explainList = JSONArray.parseArray(formExplainEntity.getExplains(), FieldAttrEntity.class);
                    saasHelp.removeExplainByBusinessType(formExplainEntity.getBusinessType(),explainList);
                    int count = 0;
                    for (int i = 0; i < explainList.size(); i++) {
                        FieldAttrEntity fieldAttrEntity = explainList.get(i);
                        String attr = fieldAttrEntity.getAttr();
                        if (count == 5) {
                            break;
                        }

                        if (!attr.contains("option")) {
                            laneListShowField.add(fieldAttrEntity.getAttr());
                            count++;
                        }
                    }
                }
                // 如果用户没有设置配置，那拨打电话也需要添加
                laneListShowField.add(ListOptionEnum.CALL.getAttr());

                //saas表单才添加默认更新时间排序
                defaultSortField.put("sortType", "desc");
                defaultSortField.put("sortAttr", "updateTime");
                resultMap.put("defaultSortField", defaultSortField);
            } else if (Objects.equals(SaasMarkEnum.PAAS.getCode(), columnSetListDTO.getSaasMark())) {
                HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                BeanUtil.copyProperties(columnSetListDTO, handlerExplainDTO);
                PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
                List<FieldAttrEntity> entityList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
                handlerExplainDTO.setExplainList(entityList);
                handlerExplainDTO.setPaasFormEntityExt(paasFormEntityExt);
                HandlerExplainVO handlerExplainVO = formDataListFormExplainHandleName.handleExplain(handlerExplainDTO);
                List<FieldAttrEntity> headList = handlerExplainVO.getHeadList();
                headList.removeIf(e ->
                        Objects.equals(FieldTypeEnum.SEPARATOR.getType(), e.getFieldType())
                                || Objects.equals(FieldTypeEnum.LOCATION.getType(), e.getFieldType())
                                || Objects.equals(FieldTypeEnum.SUB_FORM.getType(), e.getFieldType())
                                || Objects.equals(FieldTypeEnum.IMAGE.getType(), e.getFieldType())
                                || Objects.equals(FieldTypeEnum.UPLOAD.getType(), e.getFieldType())
                );
                for (int i = 0; i < headList.size(); i++) {
                    FieldAttrEntity fieldAttrEntity = headList.get(i);
                    laneListShowField.add(fieldAttrEntity.getAttr());
                    if (i == 5) {
                        break;
                    }
                }
            }

            resultMap.put("laneListShowField", laneListShowField);
            resultMap.put("laneCountField", null);
            resultMap.put("showTitle", 1);

        }
        columnSetListVO.setUserConfigMap(resultMap);
        return columnSetListVO;
    }

    @Override
    public ColumnSetAddVO laneColumnSet(ColumnSetAddDTO columnSetAddDTO) throws XbbException {
        List<ColumnSortPojo> columnSort = columnSetAddDTO.getColumnSort();
        String countField = columnSetAddDTO.getCountField() == null ? "" : columnSetAddDTO.getCountField();
        Integer showTitle = columnSetAddDTO.getShowTitle() == null ? 0 : columnSetAddDTO.getShowTitle();
        String sortAttr = StringUtil.isEmpty(columnSetAddDTO.getSortAttr()) ? "updateTime" : columnSetAddDTO.getSortAttr();
        String sortType = StringUtil.isEmpty(columnSetAddDTO.getSortType()) ? "desc" : columnSetAddDTO.getSortType();
        List<String> showList = columnSetAddDTO.getShowList();
        if (StringUtil.isNotEmpty(countField) && !countField.startsWith("num")&& !countField.startsWith("long")) {
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260062);
        }
        if (CollectionsUtil.isNotEmpty(showList)) {
            int i = 0;
            for (String temp : showList) {
                if (StringUtil.isNotEmpty(temp) && !temp.startsWith("option")) {
                    i++;
                }
            }
            if (i < 1 || i > 5) {
                throw new XbbException(ProErrorCodeEnum.API_ERROR_260061);
            }
        }else{
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260061);
        }

        ColumnSetAddVO columnSetAddVO = new ColumnSetAddVO();
        String userId = columnSetAddDTO.getUserId();
        String corpid = columnSetAddDTO.getCorpid();
        Long appId = columnSetAddDTO.getAppId();
        Long formId = columnSetAddDTO.getFormId();
        String laneDefaultSortConfigAlias = UserConfigEnum.LANE_DEFAULT_SORT_FIELD.getAlias()+"_"+ + appId + "_" + formId;
        String laneListSortFieldConfigAlias = UserConfigEnum.LANE_LIST_SORT_FIELD.getAlias()+"_"+ + appId + "_" + formId;
        String laneListShowFieldConfigAlias = UserConfigEnum.LANE_LIST_SHOW_FIELD.getAlias()+"_"+ + appId + "_" + formId;
        String laneCountFieldConfigAlias = UserConfigEnum.LANE_COUNT_FIELD.getAlias()+"_"+ + appId + "_" + formId;
        String laneShowTitleConfigAlias = UserConfigEnum.LANE_SHOW_TITLE.getAlias()+"_"+ + appId + "_" + formId;
        Map<String, Object> params = new HashMap<>();
        List<String> configAliasList = new ArrayList<>();
        configAliasList.add(laneDefaultSortConfigAlias);
        configAliasList.add(laneListSortFieldConfigAlias);
        configAliasList.add(laneListShowFieldConfigAlias);
        configAliasList.add(laneCountFieldConfigAlias);
        configAliasList.add(laneShowTitleConfigAlias);
        params.put("configAliasIn", configAliasList);
        params.put("userId", userId);
        params.put("corpid", corpid);
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        List<UserConfigEntity> userConfigList = userConfigModel.list(params);

        List<UserConfigEntity> addUserConfigList = new ArrayList<>();
        UserConfigEntity userConfigEntity = new UserConfigEntity();
        long now = DateUtil.getNow();
        userConfigEntity.setCorpid(corpid);
        userConfigEntity.setUserId(userId);
        userConfigEntity.setAddTime(now);
        userConfigEntity.setUpdateTime(now);
        JSONObject temp = new JSONObject();
        temp.put("sortAttr", sortAttr);
        temp.put("sortType", sortType);
        setUserConfigList(addUserConfigList, userConfigEntity, UserConfigEnum.LANE_DEFAULT_SORT_FIELD.getName(), laneDefaultSortConfigAlias, temp.toJSONString());
        if (CollectionsUtil.isNotEmpty(columnSort)){
            setUserConfigList(addUserConfigList, userConfigEntity, UserConfigEnum.LANE_LIST_SORT_FIELD.getName(), laneListSortFieldConfigAlias,JSONArray.toJSONString(columnSort));
        }
        setUserConfigList(addUserConfigList, userConfigEntity, UserConfigEnum.LANE_LIST_SHOW_FIELD.getName(), laneListShowFieldConfigAlias,JSONArray.toJSONString(showList));
        setUserConfigList(addUserConfigList, userConfigEntity, UserConfigEnum.LANE_COUNT_FIELD.getName(), laneCountFieldConfigAlias,countField);
        setUserConfigList(addUserConfigList, userConfigEntity, UserConfigEnum.LANE_SHOW_TITLE.getName(), laneShowTitleConfigAlias,String.valueOf(showTitle));
        UserConfigSaveBatchDTO userConfigSaveBatchDTO = new UserConfigSaveBatchDTO();
        BeanUtil.copyProperties(columnSetAddDTO, userConfigSaveBatchDTO);
        userConfigSaveBatchDTO.setUserConfigList(userConfigList);
        userConfigSaveBatchDTO.setResultList(addUserConfigList);
        userConfigSaveBatchDTO.setConfigAliasList(configAliasList);
        insertOrUpdate(userConfigSaveBatchDTO);
        return columnSetAddVO;
    }
}
